Index: sys/nfsserver/nfs_serv.c
===================================================================
RCS file: /home/ncvs/src/sys/nfsserver/nfs_serv.c,v
retrieving revision 1.156.2.2
diff -u -r1.156.2.2 nfs_serv.c
--- sys/nfsserver/nfs_serv.c	13 Mar 2006 03:06:49 -0000	1.156.2.2
+++ sys/nfsserver/nfs_serv.c	3 Jan 2007 17:14:55 -0000
@@ -569,6 +569,10 @@

 			error = lookup(&ind);
 			ind.ni_dvp = NULL;
+			if (ind.ni_cnd.cn_flags & GIANTHELD) {
+				mtx_unlock(&Giant);
+				ind.ni_cnd.cn_flags &= ~GIANTHELD;
+			}

 			if (error == 0) {
 				/*
@@ -1915,6 +1919,10 @@

 			error = lookup(&nd);
 			nd.ni_dvp = NULL;
+			if (nd.ni_cnd.cn_flags & GIANTHELD) {
+				mtx_unlock(&Giant);
+				nd.ni_cnd.cn_flags &= ~GIANTHELD;
+			}
 			if (error)
 				goto ereply;

@@ -2141,6 +2149,10 @@

 		error = lookup(&nd);
 		nd.ni_dvp = NULL;
+		if (nd.ni_cnd.cn_flags & GIANTHELD) {
+			mtx_unlock(&Giant);
+			nd.ni_cnd.cn_flags &= ~GIANTHELD;
+		}

 		if (error)
 			goto out;
@@ -2514,8 +2526,8 @@
 		tond.ni_dvp = NULL;
 		tond.ni_vp = NULL;
 		if (error) {
-			fromnd.ni_cnd.cn_flags &= ~HASBUF;
-			tond.ni_cnd.cn_flags &= ~HASBUF;
+			NDFREE(&fromnd, NDF_ONLY_PNBUF);
+			NDFREE(&tond, NDF_ONLY_PNBUF);
 		}
 	} else {
 		if (error == -1)
@@ -2809,6 +2821,12 @@
 	nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART;
 	error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
 		&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
+	if (error == 0) {
+		VATTR_NULL(vap);
+		if (v3)
+			nfsm_srvsattr(vap);
+		nfsm_srvpathsiz(len2);
+	}
 	NFSD_UNLOCK();
 	mtx_lock(&Giant);	/* VFS */
 	if (dirp && !v3) {
@@ -2818,10 +2836,6 @@
 	if (error)
 		goto out;

-	VATTR_NULL(vap);
-	if (v3)
-		nfsm_srvsattr(vap);
-	nfsm_srvpathsiz(len2);
 	MALLOC(pathcp, caddr_t, len2 + 1, M_TEMP, M_WAITOK);
 	iv.iov_base = pathcp;
 	iv.iov_len = len2;
@@ -2878,6 +2892,10 @@

 		error = lookup(&nd);
 		nd.ni_dvp = NULL;
+		if (nd.ni_cnd.cn_flags & GIANTHELD) {
+			mtx_unlock(&Giant);
+			nd.ni_cnd.cn_flags &= ~GIANTHELD;
+		}

 		if (error == 0) {
 			bzero((caddr_t)fhp, sizeof(nfh));
Index: sys/nfsserver/nfs_srvsubs.c
===================================================================
RCS file: /home/ncvs/src/sys/nfsserver/nfs_srvsubs.c,v
retrieving revision 1.136.2.2
diff -u -r1.136.2.2 nfs_srvsubs.c
--- sys/nfsserver/nfs_srvsubs.c	4 Apr 2006 15:29:51 -0000	1.136.2.2
+++ sys/nfsserver/nfs_srvsubs.c	2 Jan 2007 19:20:02 -0000
@@ -875,6 +875,10 @@
 	}
 	if (!lockleaf)
 		cnp->cn_flags &= ~LOCKLEAF;
+	if (cnp->cn_flags & GIANTHELD) {
+		mtx_unlock(&Giant);
+		cnp->cn_flags &= ~GIANTHELD;
+	}

 	/*
 	 * nfs_namei() guarentees that fields will not contain garbage
@@ -1331,6 +1335,24 @@
 	return 0;
 }

+int
+nfsm_srvnamesiz0_xx(int *s, int m, struct mbuf **md, caddr_t *dpos)
+{
+	u_int32_t *tl;
+
+	NFSD_LOCK_DONTCARE();
+
+	tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
+	if (tl == NULL)
+		return EBADRPC;
+	*s = fxdr_unsigned(int32_t, *tl);
+	if (*s > m)
+		return NFSERR_NAMETOL;
+	if (*s < 0)
+		return EBADRPC;
+	return 0;
+}
+
 void
 nfsm_clget_xx(u_int32_t **tl, struct mbuf *mb, struct mbuf **mp,
     char **bp, char **be, caddr_t bpos, int droplock)
Index: sys/nfsserver/nfsm_subs.h
===================================================================
RCS file: /home/ncvs/src/sys/nfsserver/nfsm_subs.h,v
retrieving revision 1.37
diff -u -r1.37 nfsm_subs.h
--- sys/nfsserver/nfsm_subs.h	7 Jan 2005 01:45:51 -0000	1.37
+++ sys/nfsserver/nfsm_subs.h	2 Jan 2007 19:16:30 -0000
@@ -74,6 +74,7 @@

 int	nfsm_srvstrsiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
 int	nfsm_srvnamesiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
+int	nfsm_srvnamesiz0_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
 int	nfsm_srvmtofh_xx(fhandle_t *f, struct nfsrv_descript *nfsd,
 	    struct mbuf **md, caddr_t *dpos);
 int	nfsm_srvsattr_xx(struct vattr *a, struct mbuf **md, caddr_t *dpos);
@@ -101,7 +102,7 @@
 #define	nfsm_srvpathsiz(s) \
 do { \
 	int t1; \
-	t1 = nfsm_srvnamesiz_xx(&(s), NFS_MAXPATHLEN, &md, &dpos); \
+	t1 = nfsm_srvnamesiz0_xx(&(s), NFS_MAXPATHLEN, &md, &dpos); \
 	if (t1) { \
 		error = t1; \
 		nfsm_reply(0); \
